package com.supermap.hn.traffic.services;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.github.xiaoymin.knife4j.core.model.SortModel;
import com.supermap.analyst.networkanalyst.*;
import com.supermap.data.*;
import com.supermap.hn.traffic.commontype.*;
import com.supermap.hn.traffic.config.ESConfig;
import com.supermap.hn.traffic.config.NetworkConfig;
//import com.supermap.hn.traffic.helper.CoordinateTransform;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.unit.DistanceUnit;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.GeoDistanceQueryBuilder;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.sort.GeoDistanceSortBuilder;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortMode;
import org.elasticsearch.search.sort.SortOrder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;
import org.springframework.web.client.HttpClientErrorException;

import java.io.*;
import java.math.BigDecimal;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

@Service
public class NetworkService {
    private static final Logger log = LoggerFactory.getLogger(NetworkService.class);
    private Workspace m_workspace;
    //矢量数据集类
    private DatasetVector m_datasetNetwork;
    private DatasetVector m_HdatasetNetwork;
    private DatasetVector m_KdatasetNetwork;
    private DatasetVector m_node;
    private DatasetVector trackLineRes;
    private DatasetVector edgeIDRes;
    //地图匹配类:将轨迹点进行地图匹配，目的是基于轨迹点还原真实的路径
    private MapMatching mapMatching;
    private MapMatching mapMatchingSSC;
    //SSC数据环境类
    private SSCPathAnalystSetting sscPathAnalystSetting;
    private TransportationAnalystSetting m_transportationAnalystSetting;
    @Autowired
    private Environment env;

    @Autowired
    private final NetworkConfig networkConfig;

    @Autowired
    private RestHighLevelClient restHighLevelClient;

    private Geometry m_region;

    private static String R_ID = "id";
    private static String R_NAME = "PathName";
    private static String R_UP_SPEED = "SpdLmtS2E";
    private static String R_DOWN_SPEED = "SpdLmtE2S";
    private static String R_SPEEDLIMIT = "Speedlimit";
    private static String R_DEPENDENT = "Dependent";

    private static String index="road_point";


    public NetworkService(NetworkConfig networkConfig) {

        this.networkConfig = networkConfig;
        R_NAME = this.networkConfig.getEdgeNameField();
        R_UP_SPEED = this.networkConfig.getUpLimitedSpeedField();
        R_DOWN_SPEED = this.networkConfig.getDownLimitedSpeedField();
        R_SPEEDLIMIT = this.networkConfig.getSpeedLimit();
        R_DEPENDENT = this.networkConfig.getDependent();

        log.info("初始化网络服务");

        m_workspace = new Workspace();
        WorkspaceConnectionInfo workspaceConnectionInfo = new WorkspaceConnectionInfo(this.networkConfig.getWorkspacePath());
        //打开工作空间
        m_workspace.open(workspaceConnectionInfo);

        log.info(m_workspace.getConnectionInfo().getServer().toString());

        String m_datasourceName = this.networkConfig.getDatasourceName();
        String m_datasetName = this.networkConfig.getDatasetName();
        String m_HdatasetName = this.networkConfig.getHdatasetName();
        String m_KdatasetName = this.networkConfig.getKdatasetName();
        //获取网络数据集
        Datasource datasource = m_workspace.getDatasources().get(m_datasourceName);

        m_datasetNetwork = (DatasetVector) m_workspace.getDatasources().get(m_datasourceName).getDatasets().get(m_datasetName);
        m_HdatasetNetwork = (DatasetVector) m_workspace.getDatasources().get(m_datasourceName).getDatasets().get(m_HdatasetName);
        m_KdatasetNetwork = (DatasetVector) m_workspace.getDatasources().get(m_datasourceName).getDatasets().get(m_KdatasetName);
        m_node = (DatasetVector) m_workspace.getDatasources().get(m_datasourceName).getDatasets().get("Node");
        //获取范围数据集
        String m_regionDatasetName = this.networkConfig.getRegionDatasetName();
        DatasetVector m_datasetRegion = (DatasetVector) m_workspace.getDatasources().get(m_datasourceName).getDatasets().get(m_regionDatasetName);
        m_region = initRegion(m_datasetRegion);

        //获取结果数据集
        trackLineRes = (DatasetVector) datasource.getDatasets().get("trackLineRes");
        edgeIDRes = (DatasetVector) datasource.getDatasets().get("edgeIDRes");


        //交通网络分析环境设置类
        m_transportationAnalystSetting = new TransportationAnalystSetting();
        m_transportationAnalystSetting.setNetworkDataset(m_datasetNetwork);
        m_transportationAnalystSetting.setEdgeIDField(this.networkConfig.getEdgeIDField());
        m_transportationAnalystSetting.setNodeIDField(this.networkConfig.getNodeIDField());
        m_transportationAnalystSetting.setEdgeNameField(this.networkConfig.getEdgeNameField());
        WeightFieldInfos weightFieldInfos = new WeightFieldInfos();
        WeightFieldInfo weightFieldInfo = new WeightFieldInfo();
        weightFieldInfo.setFTWeightField(this.networkConfig.getFTWeightField());
        weightFieldInfo.setTFWeightField(this.networkConfig.getTFWeightField());
        weightFieldInfo.setName(this.networkConfig.getWeightName());
        weightFieldInfos.add(weightFieldInfo);
        m_transportationAnalystSetting.setWeightFieldInfos(weightFieldInfos);
        m_transportationAnalystSetting.setFNodeIDField(this.networkConfig.getFNodeIDField());
        m_transportationAnalystSetting.setTNodeIDField(this.networkConfig.getTNodeIDField());
        mapMatching = getMapMatching(m_transportationAnalystSetting);
//        log.info("初始化的mapMatching   " + String.valueOf(mapMatching));

        //直接读取，不要自动构建了
        //构建SSC文件参数类
//        SSCCompilerParameter sscCompilerParameter = new SSCCompilerParameter();
//        //参数设置
//        sscCompilerParameter.setNetworkDataset(m_datasetNetwork); //设置网络数据集
//        sscCompilerParameter.setEdgeIDField(this.networkConfig.getEdgeID());   //设置弧段标识
//        sscCompilerParameter.setNodeIDField(this.networkConfig.getNodeID());   //设置结点标识
//        sscCompilerParameter.setFNodeIDField(this.networkConfig.getFNodeIDField());   //起始结点标识
//        sscCompilerParameter.setTNodeIDField(this.networkConfig.getTNodeIDField());   //终止结点标识
//        sscCompilerParameter.setEdgeNameField(this.networkConfig.getSccEdgeNameField());       //弧段名称
//        sscCompilerParameter.setWeightField(this.networkConfig.getFTWeightField());   //弧段权值
//        //sscCompilerParameter.setSpeedField();            //道路速度
//        sscCompilerParameter.setLevelField(this.networkConfig.getLevelField());    //道路等级
//        sscCompilerParameter.setFilePath(this.networkConfig.getSccFilePath());       //设置生成的ssc文件的路径
//        DataCompiler dataCompiler = new DataCompiler();
//        dataCompiler.compileSSCData(sscCompilerParameter);  // 将网络数据编译为包含捷径信息的SSC文件

        //SSC数据环境类
        sscPathAnalystSetting = new SSCPathAnalystSetting();
        sscPathAnalystSetting.setNetworkDataset(m_datasetNetwork);
        sscPathAnalystSetting.setSSCFilePath(this.networkConfig.getSscFilePath());
        log.info("初始化的SSC路径   " + this.networkConfig.getSscFilePath());
        //设置地图匹配对象
        mapMatchingSSC = getMapMatching(sscPathAnalystSetting);
        log.info("初始化的mapMatchingSSC   " + String.valueOf(mapMatchingSSC));


        log.info("网络服务初始化完成");
    }

    private Geometry initRegion(DatasetVector m_datasetRegion) {
        Geometry region = null;
        if(m_datasetRegion != null){
            Recordset recordset = m_datasetRegion.getRecordset(false, CursorType.STATIC);
            region = recordset.getGeometry();
            recordset.close();
            recordset.dispose();
        }
        if(region == null) {
            region = getGlobalRegion();
        }
        return region;
    }

    private Geometry getGlobalRegion() {
        double left = -180, bottom = -90, right = 180, top = 90;
        Point2D leftTop = new Point2D(left, top);
        Point2D leftBottom = new Point2D(left, bottom);
        Point2D rightBottom = new Point2D(right, bottom);
        Point2D rightTop = new Point2D(right, top);
        Point2Ds point2Ds = new Point2Ds(new Point2D[]{leftTop, leftBottom, rightBottom, rightTop, leftTop});
        return new GeoRegion(point2Ds);
    }

    public MapMatching getMapMatching(TransportationAnalystSetting transportationAnalystSetting) {
        MapMatching mapMatching = new MapMatching();
        TransportationPathAnalystSetting pathAnalystSetting = new TransportationPathAnalystSetting(transportationAnalystSetting);
        mapMatching.setPathAnalystSetting(pathAnalystSetting);
        mapMatching.setMeasurementError(this.networkConfig.getMeasurementError());
        mapMatching.setMaxLimitedSpeed(this.networkConfig.getMaxLimitedSpeed());
        return mapMatching;
    }

    public MapMatching getMapMatching(SSCPathAnalystSetting sscPathAnalystSetting) {
        MapMatching mapMatchingSSC = new MapMatching();
        mapMatchingSSC.setPathAnalystSetting(sscPathAnalystSetting);
        mapMatchingSSC.setMeasurementError(this.networkConfig.getMeasurementError());
        mapMatchingSSC.setMaxLimitedSpeed(this.networkConfig.getMaxLimitedSpeed());
        return mapMatchingSSC;
    }

    /**
     * 获取交通路网匹配信息
     *
     * @param parameter
     * @return
     */
//    public JSONObject matching(MatchParameter parameter, MapMatching mapMatching) {
//        JSONObject resultJson = new JSONObject();
//        log.info("正在使用的mapMatching   " + String.valueOf(mapMatching));
//        if (mapMatching != null && parameter != null && parameter.points != null && parameter.points.length > 0) {
//            //获取轨迹点
//            List<TrackPoint> trackPoints = getTrackPoints(parameter.points);
//            //地图匹配结果
//            MapMatchingResult mapMatchingResult = mapMatching.batchMatch(trackPoints);
//            if (mapMatchingResult != null) {
//                if (parameter.type == ResultType.LINE) {
//                    //返回地图匹配结果轨迹线
//                    GeoLine geoLine = mapMatchingResult.getTrackLine();
//                    resultJson.put("type", "Feature");
//                    //Toolkit 工具包
//                    String jsonContent = Toolkit.GeometryToGeoJson(geoLine); //Gemetry转换为GeoJson字符串
//                    JSONObject lineObj = JSON.parseObject(jsonContent);
//                    resultJson.put("geometry", lineObj);
//                    resultJson.put("properties", new JSONObject());
//                    return resultJson;
//                } else {
//                    resultJson.put("type", "FeatureCollection");
//                    //返回匹配结果的轨迹点
//                    Point2D[] resultPoints = mapMatchingResult.getRectifiedPoints();
//                    JSONArray jsonArray = new JSONArray();
//                    for (int i = 0; i < resultPoints.length; i++) {
//                        JSONObject geomObj = new JSONObject();
//                        geomObj.put("type", "Feature");
//                        Point2D point2d = resultPoints[i];  //GeoPoint描述的是地物实体，而Point2D描述的是一个位置点
//                        GeoPoint geoPoint = new GeoPoint(point2d);
//                        String jsonContent = Toolkit.GeometryToGeoJson(geoPoint);
//                        JSONObject pointObj = JSON.parseObject(jsonContent);
//                        geomObj.put("geometry", pointObj);
//                        geomObj.put("properties", new JSONObject());
//                        jsonArray.add(geomObj);
//                    }
//                    resultJson.put("features", jsonArray);
//                    return resultJson;
//                }
//            } else {
//                resultJson.put("result", "null");
//                return resultJson;
//            }
//        } else {
//            resultJson.put("error", "parameter is failed");
//            return resultJson;
//        }
//    }

    /**
     * 获取道路限速值信息
     *
     * @param
     * @return
     */
//    public LimitSpeedResult getSpeedLimit(LimitParameter limitParam) throws IOException {
//       // LimitSpeedResult result = doESquery(limitParam.point.x,limitParam.point.y);
////        LimitSpeedResult result = getNearbyPoint(limitParam.point.x,limitParam.point.y);
////
////        if(result.KLimitE2S == result.KLimitS2E) {
////            System.out.println("上下行一致");
////        }
////        else {
//        LimitSpeedResult result = new LimitSpeedResult();
//            //如果上下行不一致，执行上下行判断
//            if (mapMatching != null && limitParam != null && limitParam.point != null) {
//                //存储GPS点
//                //pushGPSPointToES(limitParam);
//                //判断点是否在范围内
//                GeoPoint geoPoint = new GeoPoint(limitParam.point.x, limitParam.point.y);
//                result.isWithin = Geometrist.isWithin(geoPoint, m_region);
//                //获取轨迹点
//                TrackPoint trackPoint = getTrackPoint(limitParam);
//               // MapMatchingLikelyResult[] mapMatchingResults = mapMatching.match(trackPoint,true);
//                log.info("本次匹配开始--------------------------------------------------------------");
//                log.info("trackPoint---" + trackPoint.toString() + "  limitParam.vehicleNo---" +  limitParam.vehicleNo);
//
//                MapMatchingLikelyResult[] mapMatchingResults = mapMatchingSSC.match(trackPoint, false);
//
//                if (mapMatchingResults != null && mapMatchingResults.length > 0) {
//                    log.info("匹配结果存在： " + mapMatchingResults.toString());
//
//                    //循环遍历获取分数最大值
//                    double maxProbability = mapMatchingResults[0].getProbability();
//                    int maxIndex = 0;
//                    for(int i = 1; i < mapMatchingResults.length; i++){
//                        if(mapMatchingResults[i].getProbability() > maxProbability){
//                            maxIndex = i;
//                            maxProbability = mapMatchingResults[i].getProbability();
//                        }
//                    }
//                    int edgesCount  = mapMatchingResults[maxIndex].getEdges().length;
//                   if(edgesCount > 0){
//                    int edgeID = mapMatchingResults[maxIndex].getEdges()[edgesCount - 1];
//                    log.info("匹配到的弧段id为：  "  +  edgeID);
//                       GeoLine trackLine = mapMatchingResults[maxIndex].getTrackLine();
//                       //将轨迹线写入数据集
//                       Recordset recordset = trackLineRes.getRecordset(false, CursorType.DYNAMIC);
//                       recordset.addNew(trackLine);
//                       recordset.update();
//                       recordset.close();
//                       recordset.dispose();
//
//                       //将弧段ID写入数据集
//                       log.info("匹配到的弧段id为：  "  +  edgeID);
//                       Recordset res = m_datasetNetwork.query(new int[]{edgeID}, "EdgeID",CursorType.STATIC);
//                       log.info("匹配到的弧段isEmpty：  "  +  res.isEmpty());
//                       boolean append = edgeIDRes.append(res);
//                       log.info("匹配到的弧段是否添加成功：  "  +  append);
//                       res.close();
//                       res.dispose();
//                   }else {
//                       log.info("没有匹配到弧段id");
//                   }
////                    int[] ids = mapMatchingResult.getEdges();
////                    int length = ids.length;
////                    if (ids != null && length > 0) {
////                        log.info("每条匹配路径经过的弧段id存在");
////                        int id = ids[length - 1];
////                        //根据 ID 进行查询
////                        Recordset recordset = m_datasetNetwork.query(new int[]{id}, CursorType.STATIC);
////                        Recordset Hrecordset = m_HdatasetNetwork.query(new int[]{id}, CursorType.STATIC);
////                        Recordset Krecordset = m_KdatasetNetwork.query(new int[]{id}, CursorType.STATIC);
////
////                        String name = recordset.getString(R_NAME);//道路名称
////
////                        int KLimitS2E = recordset.getInt32(R_UP_SPEED);//客车默认上行限速
////                        int KLimitE2S = recordset.getInt32(R_DOWN_SPEED);//客车默认下行限速
////                        int HLimit = recordset.getInt32(R_SPEEDLIMIT);//货车默认限速
////                        int KSpecialLimit = Krecordset.getInt32(R_SPEEDLIMIT);//客车特殊限速
////                        int KSpecialLimitType = Krecordset.getInt32(R_DEPENDENT);//客车特殊限速类型
////                        int HSpecialLimitS2E = Hrecordset.getInt32(R_UP_SPEED);//货车特殊上行限速
////                        int HSpecialLimitE2S = Hrecordset.getInt32(R_DOWN_SPEED);//货车特殊下行限速
////                        int HSpecialLimitType = Hrecordset.getInt32(R_DEPENDENT);//客车特殊限速类型
////
////                        int EnodeID = recordset.getInt32("EnodeID");
////                        Recordset ENodeRecordset = m_node.query(new int[]{EnodeID}, CursorType.STATIC);
////                        int SnodeID = recordset.getInt32("SnodeID");
////                        Recordset SNodeRecordset = m_node.query(new int[]{SnodeID}, CursorType.STATIC);
////                        double EX = ENodeRecordset.getDouble("X");
////                        double EY = ENodeRecordset.getDouble("Y");
////                        double EDistance = (EX - limitParam.point.x) * (EX - limitParam.point.x) + (EY - limitParam.point.y) * (EY - limitParam.point.y);
////                        double SX = SNodeRecordset.getDouble("X");
////                        double SY = SNodeRecordset.getDouble("Y");
////                        double SDistance = (SX - limitParam.point.x) * (SX - limitParam.point.x) + (SY - limitParam.point.y) * (SY - limitParam.point.y);
////                        if (EDistance > SDistance)
////                            result.Drection = "上行";
////                        else
////                            result.Drection = "下行";
////
////
////                        result.KLimitS2E = KLimitS2E;
////                        result.KLimitE2S = KLimitE2S;
////                        result.HLimit = HLimit;
////                        result.KSpecialLimit = KSpecialLimit;
////                        result.KSpecialLimitType = KSpecialLimitType;
////                        result.HSpecialLimitS2E = HSpecialLimitS2E;
////                        result.HSpecialLimitE2S = HSpecialLimitE2S;
////                        result.HSpecialLimitType = HSpecialLimitType;
////
////                        result.id = id;
////                        result.name = name;
////
////                        recordset.close();
////                        Krecordset.close();
////                        Hrecordset.close();
////                        recordset.dispose();
////                        Krecordset.dispose();
////                        Hrecordset.dispose();
////                    }
//                }
////            } else {
////                throw new HttpClientErrorException(HttpStatus.BAD_REQUEST, "parameter is failed");
////            }
//        }
//        return result;
//    }

    //查询最近的十个点
//    public LimitSpeedResult getNearbyPoint(Double lon,Double lat) throws IOException {
//        LimitSpeedResult result = new LimitSpeedResult();
//        Long  id; //查询出来的道路ID
//        SearchRequest request = new SearchRequest(index);
//        SearchSourceBuilder builder = new SearchSourceBuilder();
//        builder.size(1);
//        GeoDistanceQueryBuilder location1 = QueryBuilders.geoDistanceQuery("location").point(lat,lon).distance(1, DistanceUnit.KILOMETERS);
//        builder.query(location1);
//
//        // 获取距离多少公里 这个才是获取点与点之间的距离的
//        GeoDistanceSortBuilder sort = SortBuilders.geoDistanceSort("location",lat,lon);
//        sort.unit(DistanceUnit.METERS);
//        sort.order(SortOrder.ASC);
//        sort.point(lat,lon);
//        sort.ignoreUnmapped(true);
//        sort.sortMode(SortMode.MIN);
//
//        builder.sort(sort);
//
//        request.source(builder);
//
//        SearchResponse searchResponse = restHighLevelClient.search(request, RequestOptions.DEFAULT);;
//        SearchHits hits = searchResponse.getHits();
//        // 搜索耗时
//        Float usetime = searchResponse.getTook().millis() / 1000f;
//        System.out.println("附近的站点(" + hits.getTotalHits() + "个)，耗时("+usetime+"秒)：");
//        for (SearchHit hit : hits) {
//            result.setId(Long.parseLong(hit.getSourceAsMap().get("ID").toString()));
//            result.setName((String) hit.getSourceAsMap().get("PATHNAME"));
//            result.setDrection((String) hit.getSourceAsMap().get("DIRECTION"));
//            result.setKLimitS2E(Integer.parseInt(hit.getSourceAsMap().get("SPDLMTS2E").toString()));
//            result.setKLimitE2S(Integer.parseInt(hit.getSourceAsMap().get("SPDLMTE2S").toString()));
//
//            System.out.println(hit.toString());
//        }

        //根据查询到的点数据关联查询限速信息
//        SearchRequest hRequest = new SearchRequest("h_special_limit");
//        SearchSourceBuilder hBuilder = new SearchSourceBuilder();
//        QueryBuilder queryBuilder = QueryBuilder
//        hBuilder.query()

//        return result;
//    }

    private LimitSpeedResult doESquery(Double Lat,Double Lon) throws IOException {

        LimitSpeedResult result = new LimitSpeedResult();

        String url = "http://hz.supermap.group:9200/road_point/search";
        String param = "{                                                \n" +
                "  \"size\": 10,                                         \n" +
                "  \"sort\" : [                                          \n" +
                "    {                                                   \n" +
                "      \"_geo_distance\" : {                             \n" +
                "          \"location-field\" : ["+Lat+", "+Lon+"],      \n" +
                "          \"order\" : \"asc\",                          \n" +
                "          \"unit\" : \"m\",                             \n" +
                "          \"mode\" : \"min\",                           \n" +
                "          \"distance_type\" : \"arc\",                  \n" +
                "          \"ignore_unmapped\": true                     \n" +
                "      }                                                 \n" +
                "    }                                                   \n" +
                "  ],                                                    \n" +
                "  \"query\" : {                                         \n" +
                "    \"match_all\" : {}                                  \n" +
                "  }                                                     \n" +
                "}";
        //进行es查询到与GPS点最近路网点
        //将路网点属性赋值到result
        String ESresult = ES_Get(url, param);
        JSONObject jsonObject = JSON.parseObject(ESresult);
        JSONObject hitsjsonObject = jsonObject.getJSONObject("hits");
        System.out.print(hitsjsonObject);

        return result;
    }

    public String ES_Get(String actionUrl, String param) throws IOException {
        StringBuffer sbf = new StringBuffer();
        String strRead = null;
        URL url = new URL(actionUrl);
        HttpURLConnection connection = (HttpURLConnection)url.openConnection();
        connection.setRequestMethod("POST");//请求post方式
        connection.setDoInput(true);
        connection.setDoOutput(true);
        //header内的的参数在这里set
        //connection.setRequestProperty("key", "value");
        connection.setRequestProperty("Content-Type", "application/json");
        connection.connect();
        OutputStreamWriter writer = new OutputStreamWriter(connection.getOutputStream(),"UTF-8");
        //body参数放这里
        writer.write(param);
        writer.flush();
        InputStream is = connection.getInputStream();
        BufferedReader reader = new BufferedReader(new InputStreamReader(is, "UTF-8"));
        while ((strRead = reader.readLine()) != null) {
            sbf.append(strRead);
            sbf.append("\r\n");
        }
        reader.close();
        connection.disconnect();
        String results = sbf.toString();
        return results;
    }

    private JSONObject querySpeedLimit(Point point) {
        JSONObject resultJson = new JSONObject();
        double distance = this.networkConfig.getMeasurementError();
        // 由于超图接口距离查询是根据数据集单位来计算的，当数据集单位为度是，按照查询位置测地线长度，把查询距离米数值转换成度
        PrjCoordSys prjCoordSys = m_datasetNetwork.getPrjCoordSys(); //数据集的投影信息
        if (prjCoordSys != null) {
            Unit unit = prjCoordSys.getCoordUnit();  //返回投影系统坐标单位
            if (unit == Unit.DEGREE) {   //Unit.DEGREE 度
                //返回地球椭球体的长半径
                double majorAxis = prjCoordSys.getGeoCoordSys().getGeoDatum().getGeoSpheroid().getAxis();
                //返回地球椭球体的扁率
                double flatten = prjCoordSys.getGeoCoordSys().getGeoDatum().getGeoSpheroid().getFlatten();
                Point2Ds point2Ds = new Point2Ds(new Point2D[]{
                        new Point2D(point.x, point.y),
                        new Point2D(point.x + 1, point.y)
                });
                //计算测地线的长度
                double geodesicDistance = Geometrist.computeGeodesicDistance(point2Ds, majorAxis, flatten);
                distance = distance / geodesicDistance;
            }
        }
        GeoPoint geoPoint = new GeoPoint(point.x, point.y);
        Recordset recordset = m_datasetNetwork.query(geoPoint, distance, CursorType.STATIC);
        // 查询结果记录为空时，构造空值返回
        if (recordset.getRecordCount() == 0) {
            resultJson.put(R_ID, -1);
            resultJson.put(R_UP_SPEED, -1);
            resultJson.put(R_DOWN_SPEED, -1);
            resultJson.put(R_NAME, null);
        } else {
            // 遍历查询结果，获取距离最近的一条记录返回
            double minDistance = Double.MAX_VALUE;
            while (!recordset.isEOF()) {
                Geometry geometry = recordset.getGeometry();
                double dis = Geometrist.distance(geoPoint, geometry);
                if (dis < minDistance) {
                    minDistance = dis;
                    int id = recordset.getID();
                    int up = recordset.getInt32(R_UP_SPEED);
                    int down = recordset.getInt32(R_DOWN_SPEED);
                    String name = recordset.getString(R_NAME);
                    resultJson.put(R_ID, id);
                    resultJson.put(R_UP_SPEED, up);
                    resultJson.put(R_DOWN_SPEED, down);
                    resultJson.put(R_NAME, name);
                }
                recordset.moveNext();
            }
        }
        recordset.close();
        recordset.dispose();
        return resultJson;
    }

//    private TrackPoint getTrackPoint(LimitParameter limitParam) {
//        Point gpsPoint = limitParam.point;
//        TrackPoint trackPoint = new TrackPoint();
//        Point2D gpsPoint_gcj02 = CoordinateTransform.transformWGS84ToGCJ02(new Point2D(gpsPoint.x, gpsPoint.y));
//        trackPoint.setPoint(gpsPoint_gcj02);
//        Date date = new Date(gpsPoint.time);
//        trackPoint.setTime(date);
//        return trackPoint;
//    }

    private boolean pushGPSPointToES(LimitParameter limitParam){
        IndexRequest indexRequest = new IndexRequest(ESConfig.STR_INDEX);
        indexRequest.type("_doc");
        JSONObject jsonObject = new JSONObject();
        JSONObject point = new JSONObject();
        point.put("lon", limitParam.point.x);
        point.put("lat", limitParam.point.y);
        jsonObject.put("gps", point);
        jsonObject.put("time", limitParam.point.time);
        jsonObject.put("vehicleNo", limitParam.vehicleNo);
        indexRequest.source(jsonObject, XContentType.JSON);
        try {
            IndexResponse index = restHighLevelClient.index(indexRequest, RequestOptions.DEFAULT);
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }

    /**
     * 获取轨迹点类
     *
     * @param points
     * @return
     */
    private List<TrackPoint> getTrackPoints(Point[] points) {
        List<TrackPoint> trackPoints = new ArrayList<TrackPoint>();
        for (int i = 0; i < points.length; i++) {
            Point gpsPoint = points[i];
            TrackPoint trackPoint = new TrackPoint();
            trackPoint.setPoint(new Point2D(gpsPoint.x, gpsPoint.y));
            trackPoint.setKey(i + 1);
            Date date = new Date(gpsPoint.time);
            trackPoint.setTime(date);
            trackPoints.add(trackPoint);
        }
        return trackPoints;
    }

    /**
     * 常规匹配
     *
     * @param
     * @return
     */
//    public JSONObject matchingByMap(MatchParameter parameter) {
//        return matching(parameter, mapMatching);
//    }

    /**
     * SSC匹配
     *
     * @param
     * @return
     */
//    public JSONObject matchingBySSC(MatchParameter parameter) {
//        return matching(parameter, mapMatchingSSC);
//    }
}
